<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
  <script type="module" src="../../polymer-element.js"></script>
</head>
<body>

<template id="my-element-template">
  <style>
     :host {
       display: block;
     }
    #counter {
      padding: 10px;
      background: lightblue;
    }
  </style>
  <!-- can use declarative event listeners -->
  <button on-click="handleIncrement">Increment!</button>
  <span id="counter">[[limited]]</span>
  <x-a prop="[[limited]]"></x-a>
  <x-b></x-b>
</template>

<script type="module">
import { PolymerElement } from '../../polymer-element.js';
import { PropertyEffects } from '../../lib/mixins/property-effects.js';

customElements.define('x-a', class extends PolymerElement {
  static get observers() { return ['propChanged(prop)']; }
  constructor() {
    super();
    this.prop = 99;
  }
  propChanged(prop) {
    console.log(this.localName, 'propChanged', prop);
    this.textContent = prop;
  }
  ready() {
    super.ready();
    console.log(this.localName, 'ready');
  }
});

customElements.define('x-b', class extends PolymerElement {
  static get observers() { return ['propChanged(prop)']; }
  constructor() {
    super();
    this.prop = 77;
  }
  propChanged(prop) {
    console.log(this.localName, 'propChanged', prop);
    this.textContent = prop;
  }
  ready() {
    super.ready();
    console.log(this.localName, 'ready');
  }
});

let template = document.getElementById('my-element-template');

// Apply mixins to base class
let MyBaseClass = PropertyEffects(HTMLElement);

class MyElement extends MyBaseClass {

  // Declare observed attributes
  static get observedAttributes() { return ['counter', 'limit']; }

  constructor() {
    super();
    this.counter = 0;
    this.limit = Infinity;
  }

  // Enable accessors and flush any queued property changes
  connectedCallback() {
    this._enableProperties();
  }

  // Called once by PropertyAccessors during first property flush
  // Do one-time work like setting up Shadow DOM
  ready() {
    console.log(this.localName, 'before ready');
    this.dom = this._stampTemplate(template);
    super.ready();
    console.log(this.localName, 'after ready');
  }

  _readyClients() {
    this.attachShadow({mode: 'open'}).appendChild(this.dom);
    super._readyClients();
  }

  computeLimited(counter, limit) {
    return Math.min(counter, limit);
  }

  handleIncrement() {
    this.counter++;
  }

}

// Generate property accessors for all observed attributes
MyElement.createComputedProperty('limited', 'computeLimited(counter, limit)');
MyElement.bindTemplate(template);

// Register element
customElements.define('my-element', MyElement);
</script>


<my-element counter="10" limit="20"></my-element>

</body>
</html>